package org.corey.share.db.dao;

import java.util.List;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.corey.share.db.entity.Article;
import org.corey.share.db.manager.EM;
import org.corey.share.misc.PageData;

@SuppressWarnings("unchecked")
public class DefaultBaseDao implements BaseDao {
	private Logger log = Logger.getLogger(this.getClass().getName());

	public EntityManager getEM() {
		return EM.getEntityManager();
	}

	public <T> PageData<T> findAll(int pageSize, int pageIndex, Class<T> cls,
			String orderBy) {
		int startRecordIndex = PageData.getStartIndex(pageSize, pageIndex);
		Query query = getEM().createQuery(
				"Select a from " + cls.getSimpleName() + " a order by "
						+ orderBy);
		int totalSize=0;
		if(pageSize!=0){
			query.setFirstResult(startRecordIndex);
			query.setMaxResults(pageSize);
			Query countQuery = getEM().createQuery(
					"Select count(a) from " + cls.getSimpleName() + " a");
			totalSize = this.getCount(countQuery);
		}
		List<T> pageData = query.getResultList();
		PageData<T> page = new PageData<T>(totalSize, pageSize, pageIndex,
				pageData);
		return page;
	}
	
	public <T> PageData<T> findAll(int pageSize, int pageIndex, Class<T> cls,
			Long userId, String orderBy) {
		int startRecordIndex = PageData.getStartIndex(pageSize, pageIndex);
		Query query = getEM().createQuery(
				"Select a from " + cls.getSimpleName() + " a where a.user=:user order by "
						+ orderBy);
		int totalSize=0;
		if(pageSize!=0){
			query.setFirstResult(startRecordIndex);
			query.setMaxResults(pageSize);
			Query countQuery = getEM().createQuery(
					"Select count(a) from " + cls.getSimpleName() + " a where a.user=:user");
			countQuery.setParameter("user", userId);
			totalSize = this.getCount(countQuery);
		}
		List<T> pageData = query.setParameter("user", userId).getResultList();
		PageData<T> page = new PageData<T>(totalSize, pageSize, pageIndex,
				pageData);
		return page;
	}

	public boolean remove(Object entity) {
		try {
			getEM().remove(entity);
		} catch (Exception e) {
			log.warning("remove " + entity.getClass().getName()
					+ "  entity is error");
			return false;
		}
		return true;
	}

	public boolean save(Object entity) {
		try {
			getEM().persist(entity);
		} catch (Exception e) {
			log.warning("save " + entity.getClass().getName()
					+ "  entity is error");
			return false;
		}

		return true;
	}

	public boolean update(Object entity) {
		try {
			getEM().merge(entity);
		} catch (Exception e) {
			log.warning("update " + entity.getClass().getName()
					+ "  entity is error");
			return false;
		}
		return true;
	}

	protected int getCount(Query query) {
		int total = ((Integer) query.getSingleResult()).intValue();
		return total;
	}

	public Object load(Long key, Class clazz) {
		Object e = getEM().find(clazz, key);
		return e;
	}
}